// 导入 axios
import axios from "axios";
// 导入自己封装的 history 用来跳转。useHistory 在单纯的ts文件里面无法使用
import history from "./history";
// 导入自己封装的获取token信息的函数，和删除本地存储token信息的函数
import { getTokenInfo, removeTokenInfo } from "./storage";
// 请求基地址，根据开发环境和打包环境来自己设置。一般打包环境都为空
export const baseURL = process.env.NODE_ENV === "development" ? "开发环境" : "";

// 创建 axios 实例
const http = axios.create({
  baseURL,
  // 请求超过5m没有回来即停止请求，并且抛出异常
  timeout: 5000,
});

// 设置一个请求状态开关，判断 请求正在发送 和 所有请求都发送完毕
let axajInd = 0;

// 请求拦截器
http.interceptors.request.use(
  function (config: any) {
    // 开关数量+1，表示现在有一个请求在发送。
    axajInd++;
    //可以在这里添加业务代码，比如：显示 loding状态

    // 检查到有token，为所有请求添加请求体。Bearer字段为 我这边后端的需求，各位看自己 后端需求来修改
    const { token } = getTokenInfo();
    if (token) config.headers.Authorization = `Bearer ${token}`;
    return config;
  },
  function (err) {
    return Promise.reject(err);
  }
);

// 设置一个定时器id，防止多个请求同时发送，并且token失效的情况，多次执行 业务 代码
let timeId = -1;

// 响应拦截器
http.interceptors.response.use(
  function (response) {
    // 一个请求发送完毕
    axajInd--;
    if (axajInd === 0) {
      // 所有请求发送完毕，可以在这里添加业务代码，比如：隐藏 loding状态
    }

    // token过期，这里看后台的返回值设置的为多少
    if (response.data.code === 401) {
      // 先清理定时器，在执行。防止多次执行。即页面防抖原理
      clearTimeout(timeId);

      timeId = window.setTimeout(() => {
        // 删除本地token信息
        removeTokenInfo();
        // 这里的提示统一简单用的alert，自己根据需求更改。比如：antd的message
        alert("登录失效!");
        // 回到登录页面
        history.push("/Login");
      }, 200);
    } else if (response.data.code === 0) {
      // 请求成功，状态也成功（根据后端定义的状态值自己修改）
      // 这里暂时不做处理，我一般会根据具体需求在组件中自己定义 message
    } else {
      //这里一般是请求成功，但是状态码有问题，直接返回后端的提示信息。这里的msg是我这边后端的字段，自己根据后端字段来修改
      alert(response.data.msg);
     }

    return response.data;
  },
  async function (err) {
    // 请求错误的时候，直接把 axajInd 归零，防止页面一直处于 loding 状态
    axajInd = 0;
    // 如果在上面定义了发送请求前显示 loding状态，这里需要隐藏 loding

    // 如果因为网络原因，response没有，给提示消息
    if (!err.response) {
      alert("网络繁忙，请稍后重试");
    } else {
      // 网络没问题，后台返回了有数据
      alert("错误");
    }

    return Promise.reject(err);
  }
);

// 导出 axios 实例
export default http;
